package com.atqar.cas;

import java.util.concurrent.CountDownLatch;

import java.util.concurrent.atomic.AtomicInteger;

public class CASDemo {
    /*为什么atomicinteger不加锁也能保证数据的原子性
    incrementAndGet底层用来dowhile方法用该对象当前的值与v比较：如果相同，更新v+delta并且返回true,如果不同，继续取值然后再比较，直到更新完成。

     Unsafe是CAS的核心类，由于Java方法无法直接访问底层系统，需要通过本地（native）方法来访问，Unsafe相当于一个后门，
     Unsafe类中的所有方法都是native修饰的，也就是说Unsafe类中的方法都直接调用操作系统底层资源执行相应任务
     cas是一条CPU并发原语,JVM会帮我们实现出CAS汇编指令。这是一种完全依赖于硬件的功能，由于CAS是一种系统原语,并且原语的执行必须是连续的，
     在执行过程中不允许被中断，也就是说CAS是一条CPU的原子指令，不会造成所谓的数据不一致问题。
      */

/*
cas的缺点自旋开销大只能保证一个变量的原子操作并且会引发aba问题就是只关注头和尾就是如果我业务逻辑还没完成之间有人修改了又修改成原值我会认为没有修改
*/


    int number;

    public int getNumber() {
        return number;
    }

    public synchronized void setNumber() {
        ++number;
    }



    AtomicInteger atomicInteger=new AtomicInteger();

    public AtomicInteger getAtomicInteger() {
        return atomicInteger;
    }

    //不加锁也能保证数据的原子性
    public void setAtomicInteger() {
        atomicInteger.incrementAndGet();
    }

    public static void main(String[] args) throws InterruptedException {
        CASDemo casDemo = new CASDemo();
        CountDownLatch countDownLatch = new CountDownLatch(100);


        for (int i = 0; i < 100; i++) {
            new Thread(() -> {
                for (int i1 = 0; i1 < 100; i1++) {
                    casDemo.setNumber();
                    casDemo.setAtomicInteger();
                }
                //线程执行一个减去一个
               // countDownLatch.countDown();
            }).start();
        }

        //线程不执行完成一直等待
       //countDownLatch.await();
        //主线程获取numebr的值,不等待可能线程未执行完毕数据不对,不加锁可能数据会覆盖会丢
        System.out.println(casDemo.getNumber());

        System.out.println(Thread.currentThread().getName()+"="+casDemo.getAtomicInteger().get());
    }


}


